package cn.xieyang.gen.wrk.tansun;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.xieyang.gen.config.DBConfig;
import cn.xieyang.gen.handler.DBConfigHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class TansunAcqRefreshLocalDataBaseByDev {

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        long start1 = System.currentTimeMillis();
        doRefresh();
        log.info("耗时统计：更新数据库耗时：{}", formatDuration(start1, System.currentTimeMillis()));
    }

    private static void doRefresh() throws SQLException, ClassNotFoundException {
        // tansun mysql的版本是5.7.25
        DBConfig sourceDbConfig = DBConfig.builder()
                // 地址
                .url("jdbc:mysql://10.7.12.160:3306/omniacq_bts")
                // 用户名
                .userName("root")
                // 密码
                .password("tansun@xyk!2#")
                .build();
        DBConfig targetDbConfiger = DBConfig.builder()
                // 地址
                .url("jdbc:mysql://192.168.196.3:3306/ganjiang-db")
                // ip
                .ip("192.168.196.3")
                // 端口号
                .port("3306")
                // 用户名
                .userName("root")
                // 密码
                .password("123456")
                .build();
        // 导出配置
        String exportHost = "10.7.12.160";
        int exportPort = 3306;
        String exportUser = sourceDbConfig.getUserName();
        String exportPassword = sourceDbConfig.getPassword();

        String exportPath = "/data/";

        // 导入配置
        String importUser = targetDbConfiger.getUserName();
        String importPassword = targetDbConfiger.getPassword();
        String importPath = "/data/";

        String[] outputDatabases = {"ider_bms", "ider_frontend", "ider_frontend_mes", "ider_workflow", "ider_workflow_mes", "merchant_input", "omniacq_biz", "omniacq_bts"};
        String[] importDatabases = {"omniacq_ider_bms", "omniacq_ider_frontend", "omniacq_ider_frontend_mes", "omniacq_ider_workflow", "omniacq_ider_workflow_mes", "merchant_input", "omniacq_biz", "omniacq_bts"};
        clearDatabase(targetDbConfiger, importDatabases);

        List<String> asList = Arrays.asList(outputDatabases);
        List<Thread> threadList = new ArrayList<>();
        for (int i = 0; i < asList.size(); i++) {
            final String uid = "_importMark_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "_" +IdUtil.getSnowflakeNextIdStr();
            String outputDatabase = asList.get(i);
            String importDatabase = importDatabases[i];
            String exportAbsolutePath = exportPath + outputDatabase + "_" + uid + ".sql";
            FileUtil.del(exportAbsolutePath);
            Thread thread = new Thread(() -> {
                // 执行导出
                exportDatabases(exportHost, exportPort, exportUser, exportPassword, exportAbsolutePath, new String[]{outputDatabase});
                // 执行导入
                importDatabases(importUser, importPassword, importPath + outputDatabase + "_" + uid + ".sql", new String[]{importDatabase}, targetDbConfiger);
            });
            thread.start();
            threadList.add(thread);
        }
        threadList.stream().forEach(item -> {
            try {
                item.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
    }

    private static void exportDatabases(String host, int port, String user, String password, String outputPath, String[] databases) {
        for (String db : databases) {
            try {
                ProcessBuilder processBuilder = new ProcessBuilder(
                        "mysqldump",
                        "-h", host,
                        "-P", String.valueOf(port),
                        "-u", user,
                        "--password=" + password,  // 密码特殊字符需要处理
                        "--result-file=" + outputPath,
                        "--column-statistics=0", // 禁用列统计信息，tansun mysql的版本是5.7.25，不禁用无法导出
                        db
                );

                Process process = processBuilder.start();
                int exitCode = process.waitFor();

                if (exitCode == 0) {
                    System.out.println("导出成功: " + db);
                } else {
                    printError(process);
                    System.out.println("导出失败: " + db);
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static void importDatabases(String user, String password, String inputPath, String[] databases, DBConfig targetDbConfiger) {
        for (String db : databases) {
            File sqlFile = new File(inputPath);
            if (!sqlFile.exists()) {
                System.out.println("SQL文件不存在: " + sqlFile.getPath());
                continue;
            }

            try {
                ProcessBuilder processBuilder = new ProcessBuilder(
                        "mysql",
                        "-h", targetDbConfiger.getIp(),
                        "-P", targetDbConfiger.getPort(),
                        "-u", user,
                        "--password=" + password,
                        db
                ).redirectInput(sqlFile);

                Process process = processBuilder.start();
                int exitCode = process.waitFor();

                if (exitCode == 0) {
                    System.out.println("导入成功: " + db);
                } else {
                    printError(process);
                    System.out.println("导入失败: " + db);
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static void printError(Process process) throws IOException {
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getErrorStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.err.println(line);
            }
        }
    }

    private static void clearDatabase(DBConfig targetDbConfiger, String[] importDatabases) throws SQLException, ClassNotFoundException {
        // 连接 URL 不指定具体数据库，通过参数传递用户名和密码

        try (Connection conn = DBConfigHandler.getConn(targetDbConfiger);
             Statement stmt = conn.createStatement()) {

            for (String importDatabase : importDatabases) {
                // 删除数据库（建议添加 IF EXISTS 避免报错）
                stmt.executeUpdate("DROP DATABASE IF EXISTS " + importDatabase + "");

                // 创建数据库并指定字符集
                stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS " + importDatabase + " CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci");
            }

            System.out.println("清理数据库成功，数据库url：" + targetDbConfiger.getUrl());
        } catch (SQLException e) {
            System.err.println("操作失败：" + e.getMessage());
            e.printStackTrace();
        }
    }

    public static String formatDuration(long start, long end) {
        long totalMillis = end - start;

        long hours = totalMillis / 3600000;
        long remaining = totalMillis % 3600000;

        long minutes = remaining / 60000;
        remaining %= 60000;

        long seconds = remaining / 1000;
        long millis = remaining % 1000;

        return String.format("%d时%d分%d秒%d毫秒", hours, minutes, seconds, millis);
    }

}
